06. Set Up a Fake Repository

L5 P3 A02 Set Up A Fake Repository V2

In this step you'll set up a Fake repository called FakeTestRepository.

Step 1: Create a TasksRepository Interface

The first step towards using constructor dependency injection, is to create a common interface shared between the fake and the real class.

  1. Open DefaultTasksRepository and right click on the class name. Then select Refactor -> Extract -> Interface:

  1. Choose Extract to separate file:

  1. In the Extract Interface window, change the interface name to TasksRepository.
  2. In the Members to form interface section, check all members except the two companion members and the private methods:

  1. Click Refactor. The new TasksRepository interface should appear in the data/source package:

And DefaultTasksRepository now implements TasksRepository.

  1. Run your app (not the tests) to make sure everything is still in working order:

Step 2: Create FakeTestRepository

Now that you have the interface, you can create the DefaultTaskRepository test double.

  1. In the test source set, in data/source create the kotlin class FakeTestRepository.kt.
  2. Extend from the TasksRepository interface:

FakeTestRepository.kt

class FakeTestRepository : TasksRepository  {
}

You now will be told you need to implement the interface methods.

  1. Hover over the error until you see the suggestion menu, then click and select Implement members:

  1. Select all of the methods and press OK:

Step 3. Implement FakeTestRepository methods

  1. Add both a LinkedHashMap variable representing the current list of tasks and a MutableLiveData for your observable tasks:
    FakeTestRepository.kt
class FakeTestRepository : TasksRepository {

    var tasksServiceData: LinkedHashMap<String, Task> = LinkedHashMap()

    private val observableTasks = MutableLiveData<Result<List<Task>>>()


    // Rest of class
}

Implement the following methods:

  1. getTasks - This method should just take the tasksServiceData and turn it into a list using tasksServiceData.values.toList() and then return that as a Success result.
  2. refreshTasks - Updates the value of observableTasks to be what is returned by getTasks().
  3. observeTasks - Create a coroutine using runBlocking and run refreshTasks, then return observableTasks.

Here are those methods:

FakeTestRepository.kt

class FakeTestRepository : TasksRepository {

    var tasksServiceData: LinkedHashMap<String, Task> = LinkedHashMap()

    private val observableTasks = MutableLiveData<Result<List<Task>>>()

    override suspend fun getTasks(forceUpdate: Boolean): Result<List<Task>> {
        return Result.Success(tasksServiceData.values.toList())
    }

    override suspend fun refreshTasks() {
        observableTasks.value = getTasks()
    }

    override fun observeTasks(): LiveData<Result<List<Task>>> {
        runBlocking { refreshTasks() }
        return observableTasks
    }

    // Rest of class

}

Step 4: Add a Method for Testing to addTasks

  1. Add the addTasks method, which takes in a vararg of tasks, adds each to the HashMap and then refreshes the tasks:

FakeTestRepository.kt

    fun addTasks(vararg tasks: Task) {
        for (task in tasks) {
            tasksServiceData[task.id] = task
        }
        runBlocking { refreshTasks() }
    }

At this point you have a fake repository for testing with a few of the key methods implemented.